#include "MenuScreen.h"
#include "Gfx.h"
#include "GfxEffects.h"
#include "ResourceMgr.h"
#include "SFont.h"
#include "GameSettings.h"
#include "TreeNode.h"
#include "Timer.h"
#include "QuitScreen.h"
#include "Utils.h"
#include "Pixel.h"
#include <iostream>
using namespace std;

MenuScreen *MenuScreen::instance_ = NULL;

void
MenuScreen::
displayTitle () {
	// Blit the splash screen and wait
//	Gfx *gfx = Gfx::instance();
	//SDL_Surface *disp    = gfx->getScreen();
	SDL_Surface *splash  = ResourceMgr::instance()->getGfx("title.png");

/*
	SDL_Rect rect;
	rect.x = rect.y = 0;
	rect.w = 1024;
	rect.h = 768;

	SDL_BlitSurface (splash, &rect, disp, &rect);
	SDL_UpdateRects (disp, 1, &rect);
*/
				faderZoneIn(splash);
}

static
TreeNode *createMenu () {
	TreeNode *root = new TreeNode("Root", 7);
  TreeNode *play = new TreeNode("Play", 0, root);
//	CommandTreeNode *play = new CommandTreeNode("Play", root, SplashScreen::instance());
	TreeNode *highscores = new TreeNode("Highscores", 2, root);
		TreeNode *local = new TreeNode("Local", 0, highscores);
		TreeNode *network = new TreeNode("Network", 0, highscores);
	TreeNode *options = new TreeNode("Options", 1, root);
		const char *difficultyStrings[] = {
				"Easy",
				"Normal",
				"Hard",
				"Insane"
		};
		StringTreeNode *difficulty = new StringTreeNode("Difficulty", 4, difficultyStrings, options, &settings.difficulty);
//		TreeNode *easy = new TreeNode("Easy", 0, options);
//		TreeNode *normal = new TreeNode("Normal", 0, options);
//		TreeNode *hard = new TreeNode("Hard", 0, options);
//		TreeNode *insane = new TreeNode("Insane", 0, options);
	TreeNode *config = new TreeNode("Settings", 2, root);
		TreeNode *gfx = new TreeNode("Graphics", 1, config);
			BoolTreeNode *fullscreen = new BoolTreeNode("Fullscreen", gfx, settings.fullscreen);
		TreeNode *snd = new TreeNode("Sound", 1, config);
			BoolTreeNode *mute = new BoolTreeNode("Mute", snd, settings.mute);
	TreeNode *help = new TreeNode("Help", 0, root);
	TreeNode *credits = new TreeNode("Credits", 0, root);
	CommandTreeNode *quit = new CommandTreeNode("Quit", root, QuitScreen::instance());

	return root;
}

void
MenuScreen::
handleMenu () {
	Gfx *gfx = Gfx::instance();
	SDL_Surface *disp = gfx->getScreen();
	SDL_Surface *back = ResourceMgr::instance()->getGfx("title.png");
	SDL_Surface *up   = ResourceMgr::instance()->getGfx("uparrow.png");
	SDL_Surface *down = ResourceMgr::instance()->getGfx("downarrow.png");

	SDL_Rect rects[3]   = {
		{ 467, 352, up->w, up->h },
		{ 467, 561, down->w, down->h },
		{ 467-100, 352+up->h, 467+up->w+100, 561-(352+up->h) }
	};

	SDL_Rect upsrc   = { 0, 0, rects[0].w, rects[0].h };
	SDL_Rect downsrc = { 0, 0, rects[1].w, rects[1].h };

	int alpha     =  0;
	int alphasign = +10;
	int done = 0;
	SDL_Event evt;

	TreeNode *root = createMenu ();
	TreeNode *node = root;
	int nChildren;
	int childIndex = 0;
	TreeNode **children = node->getChildren(nChildren);
  TreeNode *current   = children[childIndex];

	const char *item = current->getText();

	bool changed = true;

  Timer::tick();

	for (;!done;) {
		while (SDL_PollEvent(&evt) > 0) {

				if (evt.type == SDL_QUIT) {
								QuitScreen::instance()->start();
				}
				else if (evt.type == SDL_KEYDOWN) {
						switch (evt.key.keysym.sym) {
								// TEST ONLY
								case SDLK_t:
										cout << "Fullscreen: " << settings.fullscreen << endl;
										cout << "Mute:       " << settings.mute << endl;
										cout << "Difficulty: " << settings.difficulty << endl;
										break;
								case SDLK_ESCAPE:
										QuitScreen::instance()->start();
								default:
										break;
						}
				}
				else if (evt.type == SDL_MOUSEBUTTONDOWN) {
						SDL_MouseButtonEvent *bevt = &evt.button;

						if (((Utils::inRect(bevt->x, bevt->y, &rects[0])) && (getpixel(up,bevt->x-rects[0].x, bevt->y-rects[0].y) != up->format->colorkey)) ||
								  (Utils::inRect(bevt->x, bevt->y, &rects[2]) && (bevt->button == SDL_BUTTON_WHEELUP))) {
								if (childIndex == 0) {
										childIndex = nChildren - 1;
								}
								else {
										--childIndex;
								}
								changed = true;
						}
						else if (((Utils::inRect(bevt->x, bevt->y, &rects[1])) && (getpixel(down,bevt->x-rects[1].x, bevt->y-rects[1].y) != down->format->colorkey)) ||
										(Utils::inRect(bevt->x, bevt->y, &rects[2]) && (bevt->button == SDL_BUTTON_WHEELDOWN))) {
								if (childIndex == nChildren - 1) {
										childIndex = 0;
								}
								else {
										++childIndex;
								}
								changed = true;
						}
						else if (Utils::inRect(bevt->x, bevt->y, &rects[2])) {
								if (bevt->button == SDL_BUTTON_LEFT) {
												cout << "ITEM" << endl;
										node->setSelected (children[childIndex]);	
										if (children[childIndex]->getNChildren() > 0) {
												node = children[childIndex];
												children = node->getChildren(nChildren);
												childIndex = node->getSelectedIndex ();
												changed = true;
										}
								}
								else if (bevt->button == SDL_BUTTON_RIGHT) {
										if (node != root) {
												node = node->getParent();
												children = node->getChildren(nChildren);
												childIndex = node->getSelectedIndex ();
												changed = true;
										}
								}
						}
				}
		}

		if (changed) {
			item = children[childIndex]->getText();
		  current->blitMask();
      current = children[childIndex];
			current->blitText();
			changed = false;
		}

		SDL_BlitSurface (back, &rects[0], disp, &rects[0]);
		SDL_BlitSurface (back, &rects[1], disp, &rects[1]);

		SDL_SetAlpha(up, SDL_SRCALPHA, alpha);
		SDL_SetAlpha(down, SDL_SRCALPHA, alpha);

		SDL_BlitSurface (up, &upsrc, disp, &rects[0]);
		SDL_BlitSurface (down, &downsrc, disp, &rects[1]);

		Timer::tickAndWait(15);
		SDL_UpdateRects (disp, 2, rects);
		Timer::tick();

		alpha += alphasign;
		if ((alpha <= 0) || (alpha >= 255))
			{ alphasign = -alphasign; }
	
	} // For (;!done;)

	delete root;
}

void
MenuScreen::
start () {
	GameComponent::start();

	displayTitle();
	handleMenu();
	
	switch_to("");
}

void
MenuScreen::
stop () {
	GameComponent::stop();
}

